package com.foreveross.mofang.datapersistence.infra.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.foreveross.mofang.datapersistence.infra.service.IHabseMapToMap;

/**
 * 将从habse中查询出的平级map数据模式转成要to json的层级map对象 
 * 
 * @author fb
 */
public class HbaseMapToJsonMap implements IHabseMapToMap<String, Object> {

	private static final Logger logger = LoggerFactory.getLogger(HbaseMapToJsonMap.class);
	
	// 当对应父层级为空（即第二层时）标识
	private static final String TOP = "top";
	
	// 对应map中的子集层级信息
	private static final String CHILD_LAYER = "childLayer";
	
	private static final String LIST = "list";

	private Map<String, List<Entry<String, Object>>> sameLayer = new HashMap<String, List<Entry<String, Object>>>();

	private Map<String, List<Map<String, Object>>> groupLayerMap = new HashMap<String, List<Map<String, Object>>>();
	
	private Map<String, Object> jsonMap;

	private Map<String, Object> hbaseMap;
	
	private int collectionIndex = 0;

	public HbaseMapToJsonMap() {

	}

	public HbaseMapToJsonMap(Map<String, Object> jsonMap, Map<String, Object> hbaseMap) {
		super();
		this.jsonMap = jsonMap;
		this.hbaseMap = hbaseMap;
	}

	/**
	 * 数据转换 ,主要将map中的-1、-1-1等key平级形式变成层级对象以方便json序列化
	 */
	public Map<String, Object> translation() {
		String key = null;
		String[] splitArryKey = null;
		List<Entry<String, Object>> list = null;
		
		if (hbaseMap == null || hbaseMap.isEmpty()) {
			logger.debug("需要转换map为空，将反回一个空map对象");

			return jsonMap;
		}
		
		for (Entry<String, Object> entry : hbaseMap.entrySet()) {
			splitArryKey = entry.getKey().split("_");
			
			// 把带有层级的分组存放
			if (splitArryKey.length > 1) {
				key = String.valueOf(splitArryKey.length);
				list = sameLayer.get(key);
				list = list == null ? new ArrayList<Entry<String,Object>>() : list;
				list.add(entry);
				sameLayer.put(key, list);
				
				continue;
			}
			
			jsonMap.put(entry.getKey(), entry.getValue());
		}
		
		sameLayerGroup();
		hierarchyAssembly();
		
		return jsonMap;
	}

	/**
	 * 把相同层级的分组
	 */
	private void sameLayerGroup() {
		String key = null;
		Set<String> groupkey = null;
		boolean isSecond = false; 
		
		for (Entry<String, List<Entry<String,Object>>> entryList : sameLayer.entrySet()) {
			groupkey = new HashSet<String>();
			String parentKeyPrefix = null;
			// 如果是第二层，key的截取不同
			isSecond = Integer.parseInt(entryList.getKey()) > 2 ? false : true;
			
			// 先分出每次里有多少个list对象
			for (Entry<String,Object> entry : entryList.getValue()) {
				key = entry.getKey().trim();
				groupkey.add(entry.getKey().substring(entry.getKey().indexOf("_")));
			}
			
			for (String mapKey : groupkey) {
				Map<String, Object> data = new HashMap<String, Object>();
				parentKeyPrefix = isSecond ? TOP : mapKey.substring(mapKey.indexOf("_"),StringUtils.lastIndexOf(mapKey, "_", mapKey.lastIndexOf("_")));
				
				for (Entry<String,Object> entry : entryList.getValue()) {
					key = entry.getKey().trim();

					if (mapKey.equals(key.substring(key.indexOf("_")))){
						data.put(key.substring(0, key.indexOf("_")), entry.getValue());
						//data.put(key, entry.getValue());
					}
				}
				
				data.put(CHILD_LAYER, mapKey);
				List<Map<String, Object>> arryMap = groupLayerMap.get(parentKeyPrefix);
				arryMap = arryMap == null ? new ArrayList<Map<String, Object>>() : arryMap;
				arryMap.add(data);
				groupLayerMap.put(parentKeyPrefix, arryMap);
			}
		}
		
		logger.debug("按层级分组后的数据groupLayerMap为:\t\r{}\r", groupLayerMap);
	}
	
	/**
	 * 层级结构组装 
	 */
	private void hierarchyAssembly() {
		List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
		
		for (Map<String, Object> map : groupLayerMap.get(TOP)) {
			childHierarchyAssembly(groupLayerMap.get(map.get(CHILD_LAYER)), map);
			// 移除层级信息
			map.remove(CHILD_LAYER);
			list.add(map);
		}
		
		jsonMap.put(getKey(), list);
	}
	
	/**
	 * 二层级以下结构组装 
	 */
	private void childHierarchyAssembly(List<Map<String, Object>> list, Map<String, Object> parent) {
		if (list == null || list.isEmpty()) {
			return;
		}
		
		List<Map<String, Object>> childList = new ArrayList<Map<String,Object>>();
		
		for (Map<String, Object> map : list) {
			childHierarchyAssembly(groupLayerMap.get(map.get(CHILD_LAYER)), map);
			map.remove(CHILD_LAYER);
			childList.add(map);
		}
		
		parent.put(getKey(), childList);
	}
	
	private String getKey() {
		return LIST + collectionIndex++;
	}
}
